package com.ly.demo.smsriskmanager;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.ly.demo.redisTemplate.RedisUtil;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @author liuyang
 * @des 短信手机号风控  （单条间隔时间，单位时间内最大条数）
 * @Version 1.0
 * @Date: 30/07/2021 17:05
 */
public class SMS {

    @Resource public RedisUtil redisUtil;

    public void getCodeByPhone(String phone) {
        phoneRiskManagement(phone);
        String code = RandomUtil.randomString("012356789", 6);
        //缓存验证码
        redisUtil.set(RedisConstant.PHONE__USER_LOGIN_CODE + phone, code, RedisConstant.PHONE__USER_LOGIN_CODE_TIME,
            TimeUnit.MINUTES);

        //缓存手机号最新一条短信记录的时间
        redisUtil.set(RedisConstant.PHONE__SMS_INTERVAL_CODE + phone, DateUtil.now(),
            RedisConstant.PHONE__SMS_INTERVAL_CODE_TIME, TimeUnit.MINUTES);
        //把时间记录缓存到list，并更新过期时间
        redisUtil.lPush(RedisConstant.PHONE__SMS_LIST_CODE + phone, DateUtil.now());
        redisUtil.expire(RedisConstant.PHONE__SMS_LIST_CODE + phone, 24, TimeUnit.HOURS);

        //发送验证码
        //send(phone,code);
    }

    /**
     * @return void
     * @Des 手机号风控
     * @Param [phone]
     **/
    private void phoneRiskManagement(String phone) {
        if (redisUtil.exists(RedisConstant.PHONE__SMS_INTERVAL_CODE + phone)) {
            throw new MyBizException(ResponseCodeEnum.USER_VERIFY_CODE_FREQUENTLY_ERROR.getCode(),
                ResponseCodeEnum.USER_VERIFY_CODE_FREQUENTLY_ERROR.getMessage());
        }

        if (redisUtil.exists(RedisConstant.PHONE__SMS_LIST_CODE + phone)) {
            long size = redisUtil.lSize(RedisConstant.PHONE__SMS_LIST_CODE + phone);

            //数据处理 只保留最新的10个元素
            while (size > RedisConstant.PHONE__SMS_MAX_CODE_NUM) {
                redisUtil.lPop(RedisConstant.PHONE__SMS_LIST_CODE + phone);
                size = redisUtil.lSize(RedisConstant.PHONE__SMS_LIST_CODE + phone);
            }

            //判断最大条数是否达到风控阈值
            if (size == RedisConstant.PHONE__SMS_MAX_CODE_NUM) {
                //获取第一个元素的日期
                String time = (String)redisUtil.lRange(RedisConstant.PHONE__SMS_LIST_CODE + phone, 0, 0).get(0);

                DateTime now = DateUtil.date();

                long cha = now.getTime() - DateUtil.parse(time).getTime();
                double result = cha * 1.0 / (1000 * 60 * 60);
                //判断时间间隔是否大于24小时
                if (result <= 24) {
                    throw new MyBizException(ResponseCodeEnum.USER_VERIFY_CODE_LIMIT_ERROR.getCode(),
                        ResponseCodeEnum.USER_VERIFY_CODE_LIMIT_ERROR.getMessage());
                } else {
                    redisUtil.lPop(RedisConstant.PHONE__SMS_LIST_CODE + phone);
                }
            }
        }
    }
}
